package com.xiaoq.shop.repository.impl;

import com.mongodb.WriteConcern;
import com.xiaoq.shop.entity.UserCouponEntity;
import com.xiaoq.shop.repository.IUserCouponRepository;
import com.xiaoq.vo.PagingVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.UpdateOperations;
import org.mongodb.morphia.query.UpdateResults;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by chenjh on 2017/11/6.
 */
@Repository
public class UserCouponRepositoryImpl implements IUserCouponRepository {

    @Autowired
    private Datastore dataStore;

    @Override
    public UserCouponEntity getUserCouponById(String userCouponId) {
        if(StringUtils.isNotBlank(userCouponId)){
            Query<UserCouponEntity> userCouponEntityQuery = dataStore.find(UserCouponEntity.class)
                    .field("_id").equal(userCouponId)
                    .filter("state !=", UserCouponEntity.StateEnum.DELETE.value());
            return userCouponEntityQuery.get();
        }
        return null;
    }

    @Override
    public List<UserCouponEntity> getUserAllCouponList(String shopId, String userId) {
        if(StringUtils.isBlank(userId)){
            return new ArrayList<>();
        }
        Query<UserCouponEntity> userCouponEntityQuery = dataStore.find(UserCouponEntity.class)
                .filter("state !=", UserCouponEntity.StateEnum.LOCKED.value())
                .filter("state !=", UserCouponEntity.StateEnum.DELETE.value());

        if(StringUtils.isBlank(shopId)){
            userCouponEntityQuery.field("userId").equal(userId).order("-expirationDate");
        }else {
            userCouponEntityQuery.field("shopId").equal(shopId)
                    .field("userId").equal(userId).order("-expirationDate");
        }
        return userCouponEntityQuery.asList();
    }

    @Override
    public boolean updateUserCoupon(String userCouponId, String userId, int userCouponState) {
        if(StringUtils.isAnyBlank(userCouponId, userId)){
            return false;
        }
        Query<UserCouponEntity> userCouponEntityQuery = dataStore
                .createQuery(UserCouponEntity.class)
                .filter("_id", userCouponId)
                .filter("userId", userId);

        UpdateOperations<UserCouponEntity> updateOperations = dataStore
                .createUpdateOperations(UserCouponEntity.class)
                .set("state", userCouponState)
                .set("updatedAt", System.currentTimeMillis());

        UpdateResults updateResults = dataStore.update(userCouponEntityQuery, updateOperations,false, WriteConcern.ACKNOWLEDGED);
        return updateResults.getUpdatedExisting();
    }

    @Override
    public long getUserCouponCount(String userId) {
        if(StringUtils.isBlank(userId)){
            return 0L;
        }
        long count = dataStore.createQuery(UserCouponEntity.class)
                .filter("userId", userId)
                .filter("state !=", UserCouponEntity.StateEnum.DELETE.value())
                .filter("state !=", UserCouponEntity.StateEnum.LOCKED.value())
                .count();
        return count;
    }

    @Override
    public long getUserCouponCount(String userId, String couponInstanceCode) {
        if(StringUtils.isBlank(userId)){
            return 0L;
        }
        long count = dataStore.createQuery(UserCouponEntity.class)
                .filter("userId", userId)
                .filter("couponInstanceCode", couponInstanceCode)
                .count();
        return count;
    }

    @Override
    public List<UserCouponEntity> getUserCouponList(String userId, String couponInstanceCode) {
        if(StringUtils.isAnyBlank(userId, couponInstanceCode)){
            return new ArrayList<>();
        }
        Query<UserCouponEntity> couponEntityQuery = dataStore.createQuery(UserCouponEntity.class)
                .filter("userId", userId)
                .filter("state !=", 3)
                .filter("couponInstanceCode", couponInstanceCode);

        return couponEntityQuery.asList();
    }

    @Override
    public boolean save(UserCouponEntity userCoupon) {
        if(userCoupon==null || StringUtils.isBlank(userCoupon.getId())){
            return false;
        }
        dataStore.save(userCoupon);
        return true;
    }

    @Override
    public List<UserCouponEntity> getNotExpiredCouponList(String shopId, String userId) {

        Query<UserCouponEntity> query = dataStore.createQuery(UserCouponEntity.class)
                .filter("state =", UserCouponEntity.StateEnum.NOUSE.value())
                .filter("expirationDate >", System.currentTimeMillis());
        if(StringUtils.isNotBlank(shopId)){
            query.filter("shopId", shopId);
        }
        if(StringUtils.isNotBlank(userId)){
            query.filter("userId", userId);
        }

        return query.asList();
    }

    @Override
    public List<UserCouponEntity> getUserCouponList(String shopId, List<String> couponInstanceCodeList) {
        if(StringUtils.isBlank(shopId)){
            return new ArrayList<>();
        }
        Query<UserCouponEntity> query = dataStore.createQuery(UserCouponEntity.class)
                .filter("shopId", shopId);
        if(CollectionUtils.isNotEmpty(couponInstanceCodeList)){
            query.filter("couponInstanceCode in ", couponInstanceCodeList);
        }
        return query.asList();
    }

    /**
     * 定时任务用
     * @param couponInstanceCodeList 优惠券主键列表
     * @param pagingVo 分页参数
     * @return
     */
    @Override
    public List<UserCouponEntity> getUserCouponList4Schedule(List<String> couponInstanceCodeList, PagingVo pagingVo){
        if(CollectionUtils.isEmpty(couponInstanceCodeList)){
            return new ArrayList<>();
        }
        Query<UserCouponEntity> query = dataStore.createQuery(UserCouponEntity.class)
                .filter("expirationDate >", System.currentTimeMillis())
                .filter("state =", UserCouponEntity.StateEnum.NOUSE.value())
                .filter("couponInstanceCode in ", couponInstanceCodeList);

        return query.asList();
    }
}
